package com.example.workmanagerdemo;

import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.Observer;
import androidx.work.BackoffPolicy;
import androidx.work.Constraints;
import androidx.work.Data;
import androidx.work.ExistingPeriodicWorkPolicy;
import androidx.work.NetworkType;
import androidx.work.OneTimeWorkRequest;
import androidx.work.PeriodicWorkRequest;
import androidx.work.WorkContinuation;
import androidx.work.WorkInfo;
import androidx.work.WorkManager;

import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;

import com.google.common.util.concurrent.ListenableFuture;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {

    public static final String INPUT_DATA = "input_data";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                TestData.getInstance().update();
            }
        });

        /**
         *  设置任务触发条件
         */
        //充电时，网络已连接，电池电量充足
        Constraints constraints = new Constraints.Builder()
//                .setRequiresCharging(true)
                .setRequiredNetworkType(NetworkType.CONNECTED)
//                .setRequiresStorageNotLow(true)
                .build();

        //传递参数(小的基本数据类型)
        Data dataInput = new Data.Builder()
                .putString(INPUT_DATA, "hello:" + TestData.getInstance().getData())
                .build();

        /**
         * 一次性任务：把任务触发条件设置到 request 中去
         */
        OneTimeWorkRequest request = new OneTimeWorkRequest.Builder(UploadLogWorker.class)
                //传递参数
                .setInputData(dataInput)
                //设置触发条件
                .setConstraints(constraints)
                //设置满足触发条件后，延迟10s执行
                .setInitialDelay(10, TimeUnit.SECONDS)
                //设置指数退避算法（过段事件重试任务）
                .setBackoffCriteria(BackoffPolicy.LINEAR, OneTimeWorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS)
                //设置任务tag 标签（用于跟踪任务状态和取消任务）
                .addTag("UploadTag")
                .build();
        /**
         * 周期性任务:若收到success或failure表明任务彻底终止，所以，观察者中不会有 success 通知，因为其一直在执行，
         */
        PeriodicWorkRequest request1 = new PeriodicWorkRequest.Builder(UploadLogWorker.class, 15, TimeUnit.SECONDS)
                .setInitialDelay(10, TimeUnit.SECONDS)
                .setConstraints(constraints)
                .setInputData(dataInput)
                .addTag("UploadTag1")
                .build();

        //把任务提交给系统来执行
        WorkManager.getInstance(this).enqueueUniquePeriodicWork("UploadTag1", ExistingPeriodicWorkPolicy.KEEP,request1);
    /*    new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Log.i("aaaa", "cancelAllWorkByTag: UploadTag1");
                WorkManager.getInstance(MainActivity.this).cancelAllWorkByTag("UploadTag1");
            }
        }, 5 * 1000);*/

        //获取WorkInfo（id，tag,outputData）
        //WorkManager.getInstance(this).getWorkInfosByTag("UploadTag");
        WorkManager.getInstance(this).getWorkInfoByIdLiveData(request1.getId()).observe(this, new Observer<WorkInfo>() {
            @Override
            public void onChanged(WorkInfo workInfo) {
                Log.d("aaaa", "workInfo: " + workInfo);
                //条件：任务执行成功
               /* if (workInfo != null && workInfo.getState() == WorkInfo.State.SUCCEEDED) {
                    //获取返回结果
                    Data outputData = workInfo.getOutputData();
                    String dataString = outputData.getString(UploadLogWorker.OUTPUT_DATA);

                    Log.d("aaaaa", "Worker SUCCEEDED outputData: " + dataString);
                }*/
            }
        });

        /**
         * 取消任务
         */
        //WorkManager.getInstance(this).cancelAllWorkByTag("UploadTag");
        //WorkManager.getInstance(this).cancelWorkById(request.getId());


        /**
         *  任务链: compress + updateLocal(这两个没有顺序) -> uploadRequest
         */
        OneTimeWorkRequest compressRequest = new OneTimeWorkRequest.Builder(UploadLogWorker.class)
                .build();
        OneTimeWorkRequest updateLocalRequest = new OneTimeWorkRequest.Builder(UploadLogWorker.class)
                .build();
        List<OneTimeWorkRequest> workRequestList = new ArrayList<>();
        workRequestList.add(compressRequest);
        workRequestList.add(updateLocalRequest);

        OneTimeWorkRequest uploadRequest = new OneTimeWorkRequest.Builder(UploadLogWorker.class)
                .build();

        WorkManager.getInstance(this)
                //list中 request 没有执行顺序
                .beginWith(workRequestList)
                //list中任务执行完成才执行 then
                .then(uploadRequest)
                .enqueue();

        /**
         *  任务链组合：
         *  A+B -> E
         *  C+D -> E
         */
 /*       OneTimeWorkRequest requestA = new OneTimeWorkRequest.Builder(UploadLogWorker.class).build();
        OneTimeWorkRequest requestB = new OneTimeWorkRequest.Builder(UploadLogWorker.class).build();
        OneTimeWorkRequest requestC = new OneTimeWorkRequest.Builder(UploadLogWorker.class).build();
        OneTimeWorkRequest requestD = new OneTimeWorkRequest.Builder(UploadLogWorker.class).build();
        OneTimeWorkRequest requestE = new OneTimeWorkRequest.Builder(UploadLogWorker.class).build();

        WorkContinuation workContinuation1 = WorkManager.getInstance(this).beginWith(requestA).then(requestB);
        WorkContinuation workContinuation2 = WorkManager.getInstance(this).beginWith(requestC).then(requestD);
        List<WorkContinuation> list = new ArrayList<>();
        list.add(workContinuation1);
        list.add(workContinuation2);

        WorkContinuation.combine(list)
                .then(requestE)
                .enqueue();*/

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        TestData.getInstance().release();
    }
}